import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Article as ArticleEntity } from '@/entity/Article';
import { DataSource, Repository, DeepPartial } from 'typeorm';
import { CommonService } from '../common/common.service';
import { PaginationConfig } from '@/types';
import { querySimplify } from '@/utils/queryBuildUtils';

@Injectable()
export class ArticleService extends CommonService<ArticleEntity> {
  constructor(
    @InjectRepository(ArticleEntity)
    private readonly articleRepository: Repository<ArticleEntity>,
    private dataSource: DataSource,
  ) {
    super(articleRepository);
  }

  async getArticleWidthUserById(id: number) {
    const articleEntity = await this.articleRepository.findOne({
      where: {
        id,
      },
      join: {
        alias: 'article',
        leftJoinAndSelect: {
          user: 'article.user',
        },
      },
    });
    return articleEntity;
  }

  async getArticleByWhere(findWhere: Partial<ArticleEntity>) {
    return await this.articleRepository.findOne({
      where: findWhere,
    });
  }

  async findAllAndCount(
    findOption: DeepPartial<ArticleEntity>,
    pagination: PaginationConfig,
  ) {
    const tagIds = findOption.tagIds as Array<number> | undefined;
    let tagIdsStr = '';
    if (tagIds.length) {
      tagIdsStr = tagIds?.map(() => `[${tagIds.join('|')}]`).join('.*');
      tagIdsStr = `.*${tagIdsStr}.*`;
    }
    let sqlPromise = this.articleRepository
      .createQueryBuilder('article')
      .leftJoinAndSelect('article.user', 'user');

    // 简化判断信息
    sqlPromise = querySimplify(sqlPromise, {
      ['article.id']: findOption.id,
      ['article.status']: findOption.status,
      ['article.headline']: findOption.headline && {
        operate: 'LIKE',
        value: `%${findOption.headline || ''}%`,
      },
      ['article.outline']: findOption.outline && {
        operate: 'LIKE',
        value: `%${findOption.outline || ''}%`,
      },
      ['article.user_id']: findOption.userId,
      ['article.tag_ids']: tagIdsStr && {
        operate: 'REGEXP',
        value: tagIdsStr,
      },
    });
    const [list, total] = await Promise.all([
      sqlPromise
        .skip(pagination.pageSize * (pagination.current - 1))
        .take(pagination.pageSize)
        .getMany(),
      sqlPromise.getCount(),
    ]);
    return {
      list,
      total,
    };
  }
}
